#ifndef CONTROL_TERMINAL_H_INCLUDED
#define CONTROL_TERMINAL_H_INCLUDED

#include <utils/static_event_queue.h>
#include <utils/static_io_notifier.h>

#include <utils/pthread_mutex.h>
#include <utils/config_reader.h>

#include <modem/modem_control_service.h>
#include <video/video_control_service.h>

class ControlDispatcher;

class ControlTerminal
    : public utils::static_io_notifier<ControlTerminal, ControlDispatcher, 3>
{
    class SignalDispatcher;
    class CommandDispatcher;
    class EventDispatcher;

    typedef utils::static_event_queue<20, ControlTerminal> queue_t;

public:
    typedef queue_t::event_t     ControlEvent;
    typedef ControlEvent::base_t BaseEvent;

    explicit ControlTerminal(char const * conf);

    int exec();

public /*[async]*/:
    bool warning();
    bool alarm();

public /*[events]*/:
    bool on_data_in(ControlDispatcher * ctx);
    bool on_data_out(ControlDispatcher * ctx);
    bool on_hangup(ControlDispatcher * ctx);
    bool on_error(ControlDispatcher * ctx, int err);

private /*[events]*/:
    bool onWarning(BaseEvent const & event);
    bool onAlarm(BaseEvent const & event);

private /*[handlers]*/:
    bool onSignal(int signo);
    bool onCommand(char const * comm, size_t len);
    bool onEvent(uint64_t counter);

private:
    inline bool emit(ControlEvent const & event);

    utils::config_reader config_;

    ModemControlService modemCtrl_;
    VideoControlService videoCtrl_;

    EventDispatcher * eventDisp_;

    utils::pthread_mutex queueMutex_;

    queue_t queue_;
};

#endif // CONTROL_TERMINAL_H_INCLUDED
